﻿using System.ComponentModel;
using System.Diagnostics.CodeAnalysis;
using System.Reflection;
using System.Windows;
using Pfz.Extensions;

namespace Pfz.WpfControls
{
	/// <summary>
	/// Class that holds the information of a binding to a property.
	/// </summary>
	[TypeConverter(typeof(PropertyBindingConverter))]
	public class PropertyBinding:
		Freezable
	{
		#region Static Area
			/// <summary>
			/// Dependency Property for "Property".
			/// </summary>
			public static readonly DependencyProperty PropertyProperty =
				DependencyProperty.Register
				(
					"Property",
					typeof(PropertyInfo),
					typeof(PropertyBinding)
				);

			/// <summary>
			/// Dependency Property for "DisplayName".
			/// </summary>
			public static readonly DependencyProperty DisplayNameProperty =
				DependencyProperty.Register
				(
					"DisplayName",
					typeof(string),
					typeof(PropertyBinding)
				);
		#endregion


		/// <summary>
		/// The property to bound-to.
		/// </summary>
		[TypeConverter(typeof(PropertyInfoConverter))]
		public PropertyInfo Property
		{
			get
			{
				return (PropertyInfo)GetValue(PropertyProperty);
			}
			set
			{
				SetValue(PropertyProperty, value);
			}
		}
		
		/// <summary>
		/// The display name to be used. A null value means that the default
		/// display name of the property will be used.
		/// </summary>
		public string DisplayName
		{
			get
			{
				return (string)GetValue(DisplayNameProperty);
			}
			set
			{
				SetValue(DisplayNameProperty, value);
			}
		}

		/// <summary>
		/// Returns the appropriate DisplayName to use for the property.
		/// </summary>
		[SuppressMessage("Microsoft.Performance", "CA1820:TestForEmptyStringsUsingStringLength")]
		public override string ToString()
		{
			string displayName = DisplayName;
			if (displayName != null)
			{
				if (displayName == "")
					return null;

				return displayName;
			}
			
			var recordProperty = Property;
			if (recordProperty != null)
				return recordProperty.GetDisplayName();
			
			return null;
		}
		
		/// <summary>
		/// Creates a binding implicitelly from a PropertyInfo.
		/// </summary>
		public static implicit operator PropertyBinding (PropertyInfo propertyInfo)
		{
			return new PropertyBinding { Property = propertyInfo };
		}

		/// <summary>
		/// Creates a new instance of PropertyBinding.
		/// </summary>
		/// <returns></returns>
		protected override Freezable CreateInstanceCore()
		{
			return new PropertyBinding();
		}
	}
}
